package com.xxl.job.executor.sjbank.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxl.job.executor.sjbank.mapper.*;
import com.xxl.job.executor.sjbank.pojo.*;
import com.xxl.job.executor.sjbank.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.xxl.job.core.context.XxlJobHelper;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import static com.xxl.job.executor.plugin.JPubUtils.*;
import static com.xxl.job.executor.plugin.JPubUtils.ObjectToString;

/**
 * @author tsu
 * @description 针对表【credit_account(信用卡账户表)】的数据库操作Service实现
 * @createDate 2024-02-29 16:46:20
 */
@Service
public class CreditAccountServiceImpl extends ServiceImpl<CreditAccountMapper, CreditAccount>
        implements CreditAccountService {

    @Value("${batchsize}")
    private int batchSize;
    @Resource
    CreditAccountMapper creditAccountMapper;
    @Resource
    CreditCardMapper creditCardMapper;
    @Resource
    CreditAccountAmortMapper creditAccountAmortMapper;
    @Resource
    CreditAccountAmortService creditAccountAmortService;
    @Resource
    CreditAccountBalanceMapper creditAccountBalanceMapper;
    @Resource
    CreditAccountBlahistMapper creditAccountBlahistMapper;
    @Resource
    CreditAccountBillhistService creditAccountBillhistService;
    @Resource
    CreditAccountBillhistMapper creditAccountBillhistMapper;
    @Resource
    ConCustomerMapper conCustomerMapper;

    @Override
    @Transactional
    public void syncCredit() {
        XxlJobHelper.log("XXL-JOB, 同步卡账信息表开始.");

        List<LinkedHashMap> iaList = creditAccountMapper.selectCredit();
        List<LinkedHashMap> iaxList = creditAccountMapper.selectCreditAccx();
        List<LinkedHashMap> meList = creditAccountMapper.selectCreditUpl();
        XxlJobHelper.log("【信用卡账户】:{}条>>>>>【信用卡美元账户】:{}条>>>>>【UPL账户】:{}条", iaList.size(), iaxList.size(), meList.size());
        //处理账户
        CreditAccount(iaList, iaxList, meList);

        List<LinkedHashMap> icList = creditAccountMapper.selectCard();
        XxlJobHelper.log("【信用卡】:{}条", icList.size());
        //处理信用卡
        CreditCard(icList);

        List<LinkedHashMap> ibList = creditAccountMapper.selectBalance();
        List<LinkedHashMap> ibxList = creditAccountMapper.selectBalanceAccx();
        List<LinkedHashMap> mbList = creditAccountMapper.selectBalanceUpl();
        XxlJobHelper.log("【信用卡账户余额】:{}条>>>>【信用卡美元账户余额】:{}条>>>>【UPL账户余额】:{}条", ibList.size(), ibxList.size(), mbList.size());
        //处理账户余额信息
        CreditAccountBalance(ibList, ibxList, mbList);

        List<LinkedHashMap> imList = creditAccountMapper.selectAmort();
        List<LinkedHashMap> mmList = creditAccountMapper.selectAmortUpl();
        XxlJobHelper.log("【信用卡账户分期】:{}条>>>>【UPL账户分期】:{}条", imList.size(), mmList.size());
        //处理账户分期信息
        CreditAccountAmort(imList, mmList);

        XxlJobHelper.log("XXL-JOB, 同步卡账信息表结束.");
    }

    @Transactional
    public void CreditAccount(List<LinkedHashMap> iaList, List<LinkedHashMap> iaxList, List<LinkedHashMap> meList) {
        XxlJobHelper.log("XXL-JOB, 同步账户表开始.");
        SimpleDateFormat originalFormat = new SimpleDateFormat("yyyyMMdd"); // 原始格式
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<CreditAccount> insertList = new ArrayList<>();
        List<CreditAccount> updateList = new ArrayList<>();
        iaList.forEach(row -> {
            try {
                ConCustomer conCustomer = conCustomerMapper.selectOne(new QueryWrapper<ConCustomer>().eq("openacctcertno", row.get("custrnbr")));
                CreditAccount creditAccount = new CreditAccount();
                creditAccount.setAcct(ObjectToString(row.get("xaccount")));
                creditAccount.setCustNo(conCustomer.getCustomernumber());
                creditAccount.setBillDate(ObjectToString(row.get("cyclenbr")));
                creditAccount.setAcctStatus(ObjectToString(row.get("closecode")));
                creditAccount.setAcctStatusName(ObjectToString(row.get("closedesc")));
                creditAccount.setMthsOdue(ObjectToInt(row.get("mthsodue")));
                creditAccount.setMthsDay(ObjectToInt(row.get("oddt")));
                creditAccount.setOpenDt(originalFormat.parse(ObjectToString(row.get("dayopened"))));
                creditAccount.setAcctBigType("1");
                creditAccount.setCurrency("156");
                creditAccount.setAcctType(ObjectToString(row.get("category")));
                creditAccount.setCrdtCardRepeNo(ObjectToString(row.get("card_nbr")));
                creditAccount.setMddt(new Date());

                CreditAccount ca_obj = creditAccountMapper.selectOne(new QueryWrapper<CreditAccount>().eq("acct", ObjectToString(row.get("xaccount"))));
                if (ca_obj == null) {
                    creditAccount.setCrdt(new Date());
                    //save(creditAccount);
                    insertList.add(creditAccount);

                    if (insertList.size() >= batchSize) {
                        saveBatch(insertList);
                        XxlJobHelper.log("Acct Inserted batch of size: " + insertList.size());
                        insertList.clear(); // 清空列表以准备下一批
                    }
                } else {
                    //updateById(creditAccount);
                    updateList.add(creditAccount);

                    if (updateList.size() >= batchSize) {
                        updateBatchById(updateList);
                        XxlJobHelper.log("Acct Update batch of size: " + updateList.size());
                        updateList.clear(); // 清空列表以准备下一批
                    }
                }

            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB 信用卡账户同步, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        // 插入剩余的记录
        if (!insertList.isEmpty()) {
            saveBatch(insertList);
            XxlJobHelper.log("Acct Inserted final batch of size: " + insertList.size());
        }
        // 插入剩余的记录
        if (!updateList.isEmpty()) {
            updateBatchById(updateList);
            XxlJobHelper.log("Acct Update final batch of size: " + updateList.size());
        }
        iaxList.forEach(row -> {
            try {
                ConCustomer conCustomer = conCustomerMapper.selectOne(new QueryWrapper<ConCustomer>().eq("openacctcertno", row.get("custrnbr")));
                CreditAccount creditAccount = new CreditAccount();
                creditAccount.setAcct(ObjectToString(row.get("xaccount")));
                creditAccount.setCustNo(conCustomer.getCustomernumber());
                creditAccount.setBillDate(ObjectToString(row.get("cyclenbr")));
                creditAccount.setAcctStatus(ObjectToString(row.get("closecode")));
                creditAccount.setAcctStatusName(ObjectToString(row.get("closedesc")));
                creditAccount.setMthsOdue(ObjectToInt(row.get("mthsodue")));
                creditAccount.setMthsDay(ObjectToInt(row.get("oddt")));
                creditAccount.setOpenDt(originalFormat.parse(ObjectToString(row.get("dayopened"))));
                creditAccount.setAcctBigType("1");
                creditAccount.setCurrency("840");
                creditAccount.setAcctType(ObjectToString(row.get("category")));
                creditAccount.setCrdtCardRepeNo(ObjectToString(row.get("card_nbr")));
                creditAccount.setMddt(new Date());

                CreditAccount ca_obj = creditAccountMapper.selectOne(new QueryWrapper<CreditAccount>().eq("acct", ObjectToString(row.get("xaccount"))));
                if (ca_obj == null) {
                    creditAccount.setCrdt(new Date());
                    save(creditAccount);
                } else {
                    updateById(creditAccount);
                }

            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB 信用卡美元账户同步, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        meList.forEach(row -> {
            try {
                CreditAccount creditAccount = new CreditAccount();
                creditAccount.setAcct((String) row.get("lending_ref"));
                creditAccount.setCustNo((String) row.get("custnum"));
                creditAccount.setAcctStatus((String) row.get("card_state"));
                creditAccount.setMthsOdue(StringToInt((String) row.get("cum_due_period")));
                creditAccount.setMthsDay(StringToInt((String) row.get("od_dt")));
                creditAccount.setOpenDt(formatter.parse((String) row.get("start_date")));
                creditAccount.setAcctBigType("2");
                creditAccount.setCurrency("156");
                creditAccount.setAcctType((String) row.get("pro_no"));
                creditAccount.setDebitCardNum((String) row.get("pay_back_acc"));
                creditAccount.setMddt(new Date());

                CreditAccount ca_obj = creditAccountMapper.selectOne(new QueryWrapper<CreditAccount>().eq("acct", row.get("lending_ref")));
                if (ca_obj == null) {
                    creditAccount.setCrdt(new Date());
                    save(creditAccount);
                } else {
                    updateById(creditAccount);
                }

            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB UPL账户同步, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        XxlJobHelper.log("XXL-JOB, 同步账户表结束.");
    }

    private void CreditCard(List<LinkedHashMap> icList) {
        XxlJobHelper.log("XXL-JOB, 同步卡片表开始.");
        icList.forEach(row -> {
            try {
                CreditCard creditCard = new CreditCard();
                ConCustomer conCustomer = conCustomerMapper.selectOne(new QueryWrapper<ConCustomer>().eq("openacctcertno", row.get("custrnbr")));
                creditCard.setAcct(ObjectToString(row.get("xaccount")));
                creditCard.setCustNo(conCustomer.getCustomernumber());
                creditCard.setCardNo(ObjectToString(row.get("cardnbr")));
                creditCard.setCardOrgNo(ObjectToString(row.get("prmagcode")));
                creditCard.setMddt(new Date());

                CreditCard cc_obj = creditCardMapper.selectOne(new QueryWrapper<CreditCard>().eq("card_no", row.get("cardnbr")));

                if (cc_obj == null) {
                    creditCard.setCrdt(new Date());
                    creditCardMapper.insert(creditCard);
                } else {
                    creditCardMapper.updateById(creditCard);
                }
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB-CreditCard, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        XxlJobHelper.log("XXL-JOB, 同步卡片表结束.");
    }

    private void CreditAccountAmort(List<LinkedHashMap> imList, List<LinkedHashMap> mmList) {
        XxlJobHelper.log("XXL-JOB, 同步账户分期表开始.");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        if (imList.size() > 0) {
            creditAccountAmortMapper.delete(null);
        }
        imList.forEach(row -> {
            try {
                //ConCustomer conCustomer = conCustomerMapper.selectOne(new QueryWrapper<ConCustomer>().eq("openacctcertno", row.get("custrnbr")));
                CreditAccountAmort creditAccountAmort = new CreditAccountAmort();
                creditAccountAmort.setAcct(ObjectToString(row.get("xaccount")));
                //creditAccountAmort.setCustNo(conCustomer.getCustomernumber());
                creditAccountAmort.setAmortSeqNum(ObjectToString(row.get("mpnumber")));
                //creditAccountAmort.setAmortDt(formatter.parse((String) row.get("inptime")));
                creditAccountAmort.setAmortTotalPrin(ObjectToBigDecimal(row.get("origpurch")));
                creditAccountAmort.setAmortTerms(ObjectToString(row.get("nbrmths")));
                //creditAccountAmort.setMonthlyAmortPrin((BigDecimal) row.get("origpurch") / (BigDecimal) row.get("nbrmths"));
                creditAccountAmort.setMonthlyAmortInt(ObjectToBigDecimal(row.get("mthint")));
                //creditAccountAmort.setRemainTerms(row.get("nbrmths") - row.get("instlcnt"));
                creditAccountAmort.setRemainTerms(ObjectToBigDecimal(row.get("instlcnt")));
                creditAccountAmort.setRemainUnbackPrin(ObjectToBigDecimal(row.get("remppl")));
                creditAccountAmort.setAmortType(ObjectToString(row.get("mptype")));
                creditAccountAmort.setAmortPayStatus(ObjectToString(row.get("status")));
                creditAccountAmort.setCredpId(ObjectToString(row.get("credpid")));
                creditAccountAmort.setCrdt(new Date());
                creditAccountAmort.setMddt(new Date());

                creditAccountAmortService.save(creditAccountAmort);
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB 信用卡分期信息同步, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        mmList.forEach(row -> {
            try {
                CreditAccountAmort creditAccountAmort = new CreditAccountAmort();
                creditAccountAmort.setAcct((String) row.get("lending_ref"));
                creditAccountAmort.setCustNo(ObjectToString(row.get("custnum")));
                creditAccountAmort.setAmortSeqNum(ObjectToString(row.get("term")));
                if (row.get("start_date") != null) {
                    creditAccountAmort.setAmortDt(formatter.parse((String) row.get("start_date")));
                }
                creditAccountAmort.setAmortTotalPrin(ObjectToBigDecimal(row.get("amount")));
                creditAccountAmort.setAmortTerms(ObjectToString(row.get("total_period")));
                creditAccountAmort.setMonthlyAmortAmt(ObjectToBigDecimal(row.get("sumrepay")));
                creditAccountAmort.setMonthlyAmortPrin(ObjectToBigDecimal(row.get("p_repay")));
                creditAccountAmort.setMonthlyAmortInt(ObjectToBigDecimal(row.get("i_repay")));
                creditAccountAmort.setRemainTerms(ObjectToBigDecimal(row.get("instlcnt")));
                //creditAccountAmort.setRemainUnbackPrin((BigDecimal) row.get("remppl"));
                //creditAccountAmort.setAmortType((String) row.get("mptype"));
                creditAccountAmort.setAmortPayStatus(ObjectToString(row.get("repay_state")));
                creditAccountAmort.setCrdt(new Date());
                creditAccountAmort.setMddt(new Date());

                creditAccountAmortService.save(creditAccountAmort);
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB UPL分期信息同步, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        XxlJobHelper.log("XXL-JOB, 同步账户分期表结束.");
    }

    private void CreditAccountBalance(List<LinkedHashMap> ibList, List<LinkedHashMap> ibxList, List<LinkedHashMap> mbList) {
        XxlJobHelper.log("XXL-JOB, 同步账户余额表开始.");
        ibList.forEach(row -> {
            try {
                ConCustomer conCustomer = conCustomerMapper.selectOne(new QueryWrapper<ConCustomer>().eq("openacctcertno", row.get("custrnbr")));
                CreditAccountBalance creditAccountBalance = new CreditAccountBalance();
                creditAccountBalance.setAcct(ObjectToString(row.get("xaccount")));
                creditAccountBalance.setCustNo(conCustomer.getCustomernumber());
                creditAccountBalance.setCredLimit((BigDecimal) row.get("cred_limit"));
                creditAccountBalance.setLowestRepayBal((BigDecimal) row.get("stm_mindue"));
                creditAccountBalance.setAcctDebtAll((BigDecimal) row.get("acctdebtall"));
                //creditAccountBalance.setAge1Age6((BigDecimal) row.get("age1age6"));
                creditAccountBalance.setAge1Age6((BigDecimal) row.get("age"));
                creditAccountBalance.setSettledBillAmt((BigDecimal) row.get("acctdebtall"));
                creditAccountBalance.setOverPrin((BigDecimal) row.get("overprin"));
                creditAccountBalance.setInterestFee((BigDecimal) row.get("interest_fee"));
                creditAccountBalance.setPenchgAcc((BigDecimal) row.get("penchg_acc"));
                creditAccountBalance.setOthExpense((BigDecimal) row.get("other_fees"));
                creditAccountBalance.setStmBalnce((BigDecimal) row.get("stm_balnce"));
                creditAccountBalance.setSettledBillPrin((BigDecimal) row.get("stm_balfre"));
                creditAccountBalance.setUnsettledBillPrin((BigDecimal) row.get("bal_free"));
                creditAccountBalance.setUnsettledBillInt((BigDecimal) row.get("unsettled_bill_int"));
                creditAccountBalance.setUnamortPrin((BigDecimal) row.get("mp_rem_ppl"));
                creditAccountBalance.setPaymtClrd((BigDecimal) row.get("paymt_clrd"));
                creditAccountBalance.setSettledBillInt((BigDecimal) row.get("stm_balori"));
                creditAccountBalance.setSettledBillFee((BigDecimal) row.get("stm_noint"));
                creditAccountBalance.setMddt(new Date());

                CreditAccountBalance ba_obj = creditAccountBalanceMapper.selectOne(new QueryWrapper<CreditAccountBalance>().eq("acct", ObjectToString(row.get("xaccount"))));
                if (ba_obj == null) {
                    creditAccountBalance.setCrdt(new Date());
                    creditAccountBalanceMapper.insert(creditAccountBalance);
                } else {
                    creditAccountBalanceMapper.updateById(creditAccountBalance);
                }

                CreditAccountBlahist creditAccountBlahist = new CreditAccountBlahist();
                // 将属性复制到新对象中
                BeanUtils.copyProperties(creditAccountBalance, creditAccountBlahist);
                creditAccountBlahistMapper.insert(creditAccountBlahist);
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB-信用卡账户余额, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        ibxList.forEach(row -> {
            try {
                ConCustomer conCustomer = conCustomerMapper.selectOne(new QueryWrapper<ConCustomer>().eq("openacctcertno", row.get("custrnbr")));
                CreditAccountBalance creditAccountBalance = new CreditAccountBalance();
                creditAccountBalance.setAcct(ObjectToString(row.get("xaccount")));
                creditAccountBalance.setCustNo(conCustomer.getCustomernumber());
                creditAccountBalance.setCredLimit((BigDecimal) row.get("cred_limit"));
                creditAccountBalance.setLowestRepayBal((BigDecimal) row.get("stm_mindue"));
                creditAccountBalance.setAcctDebtAll((BigDecimal) row.get("acctdebtall"));
                //creditAccountBalance.setAge1Age6((BigDecimal) row.get("age1age6"));
                creditAccountBalance.setAge1Age6((BigDecimal) row.get("age"));
                creditAccountBalance.setSettledBillAmt((BigDecimal) row.get("acctdebtall"));
                creditAccountBalance.setOverPrin((BigDecimal) row.get("overprin"));
                creditAccountBalance.setInterestFee((BigDecimal) row.get("interest_fee"));
                creditAccountBalance.setPenchgAcc((BigDecimal) row.get("penchg_acc"));
                creditAccountBalance.setOthExpense((BigDecimal) row.get("other_fees"));
                creditAccountBalance.setStmBalnce((BigDecimal) row.get("stm_balnce"));
                creditAccountBalance.setSettledBillPrin((BigDecimal) row.get("stm_balfre"));
                creditAccountBalance.setUnsettledBillPrin((BigDecimal) row.get("bal_free"));
                creditAccountBalance.setUnsettledBillInt((BigDecimal) row.get("unsettled_bill_int"));
                creditAccountBalance.setUnamortPrin((BigDecimal) row.get("mp_rem_ppl"));
                creditAccountBalance.setPaymtClrd((BigDecimal) row.get("paymt_clrd"));
                creditAccountBalance.setSettledBillInt((BigDecimal) row.get("stm_balori"));
                creditAccountBalance.setSettledBillFee((BigDecimal) row.get("stm_noint"));
                creditAccountBalance.setMddt(new Date());

                CreditAccountBalance ba_obj = creditAccountBalanceMapper.selectOne(new QueryWrapper<CreditAccountBalance>().eq("acct", ObjectToString(row.get("xaccount"))));
                if (ba_obj == null) {
                    creditAccountBalance.setCrdt(new Date());
                    creditAccountBalanceMapper.insert(creditAccountBalance);
                } else {
                    creditAccountBalanceMapper.updateById(creditAccountBalance);
                }

                CreditAccountBlahist creditAccountBlahist = new CreditAccountBlahist();
                // 将属性复制到新对象中
                BeanUtils.copyProperties(creditAccountBalance, creditAccountBlahist);
                creditAccountBlahistMapper.insert(creditAccountBlahist);
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB-信用卡美元账户余额, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        mbList.forEach(row -> {
            try {
                CreditAccountBalance creditAccountBalance = new CreditAccountBalance();
                creditAccountBalance.setAcct((String) row.get("lending_ref"));
                creditAccountBalance.setCustNo((String) row.get("custnum"));
                creditAccountBalance.setAcctDebtAll((BigDecimal) row.get("prin_od_amt"));
                creditAccountBalance.setSettledBillAmt((BigDecimal) row.get("prin_od_amt"));
                creditAccountBalance.setAge1Age6((BigDecimal) row.get("prin_od_amt"));
                creditAccountBalance.setUnsettledBillPrin((BigDecimal) row.get("balance"));
                creditAccountBalance.setPaymtClrd((BigDecimal) row.get("ab"));
                creditAccountBalance.setMddt(new Date());

                CreditAccountBalance ba_obj = creditAccountBalanceMapper.selectOne(new QueryWrapper<CreditAccountBalance>().eq("acct", row.get("lending_ref")));
                if (ba_obj == null) {
                    creditAccountBalance.setCrdt(new Date());
                    creditAccountBalanceMapper.insert(creditAccountBalance);
                } else {
                    creditAccountBalanceMapper.updateById(creditAccountBalance);
                }

                CreditAccountBlahist creditAccountBlahist = new CreditAccountBlahist();
                // 将属性复制到新对象中
                BeanUtils.copyProperties(creditAccountBalance, creditAccountBlahist);
                creditAccountBlahistMapper.insert(creditAccountBlahist);
            } catch (Exception e) {
                XxlJobHelper.log("XXL-JOB-UPL账户余额, 错误日志:" + e + ">>>>>【异常列】：" + row);
            }
        });
        XxlJobHelper.log("XXL-JOB, 同步账户余额表结束.");
    }
}
